package com.sc.nft.dao;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sc.nft.entity.UserCollectionChainLog;
import com.sc.nft.entity.dto.chain.TransferLogDTO;
import com.sc.nft.entity.vo.HoldCollectionDataVO;
import com.sc.nft.entity.vo.TransferVO;
import com.sc.nft.enums.ReceivedCollectionType;
import com.sc.nft.enums.UserChainLogStatusEnum;
import com.sc.nft.enums.UserChainTypeEnum;
import com.sc.nft.mapper.UserCollectionChainLogMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;

import java.util.Date;
import java.util.List;

/**
 * 藏品链操作轨迹表(sc_user_collection_chain_log)数据DAO
 *
 * @author kancy
 * @since 2022-10-21 00:45:21
 * @description 由 Mybatisplus Code Generator 创建
 */
@Slf4j
@Repository
public class UserCollectionChainLogDao extends ServiceImpl<UserCollectionChainLogMapper, UserCollectionChainLog> {


    public int saveBatchUserCollectionChainLogRecord(List<UserCollectionChainLog> list) {
        return baseMapper.saveBatchUserCollectionChainLogRecord(list);
    }

    public Long getHalfId() {
        return baseMapper.getHalfId();
    }

    public List<UserCollectionChainLog> getNotTokenId() {
        LambdaQueryWrapper<UserCollectionChainLog> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserCollectionChainLog::getTokenId, -1);
        wrapper.last("limit 100");
        return list(wrapper);
    }

    public UserCollectionChainLog getByCollectionId(Long userCollectionId) {
        LambdaQueryWrapper<UserCollectionChainLog> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserCollectionChainLog::getUserCollectionId, userCollectionId);
        wrapper.in(UserCollectionChainLog::getType, UserChainTypeEnum.MINT, UserChainTypeEnum.TRANSFER);
        wrapper.ne(UserCollectionChainLog::getTokenId, 0);
        wrapper.last("order by id desc limit 1");
        return getOne(wrapper);
    }

    public UserCollectionChainLog getByCollectionIdAndTokenId(Long userCollectionId) {
        LambdaQueryWrapper<UserCollectionChainLog> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserCollectionChainLog::getCollectionId, userCollectionId);
        wrapper.in(UserCollectionChainLog::getType, UserChainTypeEnum.MINT, UserChainTypeEnum.TRANSFER);
        wrapper.ne(UserCollectionChainLog::getTokenId, 0);
        return getOne(wrapper);
    }

    public Page<TransferLogDTO> getTransferLog(String firstTitle, String transactionHash, String address, String toUserAddress, Date startTime, Date endTime, ReceivedCollectionType collectionType, int pageNo, int pageSize) {
        return baseMapper.getTransferLog(new Page(pageNo, pageSize), firstTitle, transactionHash, address, toUserAddress, startTime, endTime, collectionType != null ? collectionType.getCode() : null);

    }

    public List<UserCollectionChainLog> getByTypeAndStatus(UserChainTypeEnum type, UserChainLogStatusEnum status) {
        LambdaQueryWrapper<UserCollectionChainLog> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserCollectionChainLog::getType, type);
        wrapper.in(UserCollectionChainLog::getStatus, status);
//        wrapper.orderByDesc(UserCollectionChainLog::getId);
        wrapper.last("limit 100");
        return list(wrapper);
    }

    public List<UserCollectionChainLog> getByTypeAndStatusGeId(UserChainTypeEnum type, UserChainLogStatusEnum status, Long id) {
        LambdaQueryWrapper<UserCollectionChainLog> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserCollectionChainLog::getType, type);
        wrapper.in(UserCollectionChainLog::getStatus, status);
        wrapper.ge(UserCollectionChainLog::getId, id);
//        wrapper.orderByDesc(UserCollectionChainLog::getId);
//        wrapper.last("limit 100");
        return list(wrapper);
    }

    public List<UserCollectionChainLog> getByTypeAndStatusLtId(UserChainTypeEnum type, UserChainLogStatusEnum status, Long id) {
        LambdaQueryWrapper<UserCollectionChainLog> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserCollectionChainLog::getType, type);
        wrapper.in(UserCollectionChainLog::getStatus, status);
        wrapper.lt(UserCollectionChainLog::getId, id);
//        wrapper.orderByDesc(UserCollectionChainLog::getId);
//        wrapper.last("limit 100");
        return list(wrapper);
    }


    public UserCollectionChainLog getOneByUserIdAndUserCollectionId(Long userId, Long userCollectionId) {
        LambdaQueryWrapper<UserCollectionChainLog> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserCollectionChainLog::getUserId, userId);
        wrapper.eq(UserCollectionChainLog::getUserCollectionId, userCollectionId);
        wrapper.last("order by id desc limit 1");
        return getOne(wrapper);
    }

    public Page<TransferVO> getAdminCollectionChainRecord(String firstTitle, String fromUserAddress, String toUserAddress, String transactionHash, Integer collectionType, Integer status, Date startTime, Date endTime, Integer pageNo, Integer pageSize) {
        return baseMapper.getAdminCollectionChainRecord(new Page(pageNo, pageSize), firstTitle, fromUserAddress, toUserAddress, transactionHash, collectionType, status, startTime, endTime);
    }

    /**
     * 获取用户持有藏品的详情统计
     *
     * @param userId
     * @return
     */
    public List<HoldCollectionDataVO> getHoldCollectionData(Long userId, String collection) {
        return baseMapper.getHoldCollectionData(userId, collection);
    }

    public List<HoldCollectionDataVO> getSingleHoldCollectionDataByUserIdAndCollectionId(Long userId, Long collectionId) {
        return baseMapper.getSingleHoldCollectionDataByUserIdAndCollectionId(userId, collectionId);
    }

    public Page<HoldCollectionDataVO> getSingleHoldCollectionData(Long userId, Integer pageNo, Integer pageSize, Long collectionId) {
        return baseMapper.getSingleHoldCollectionData(new Page(pageNo, pageSize), userId, collectionId);
    }

    public UserCollectionChainLog findTransactionHashByToUserCollectionId(Long toUserCollectionId) {
        LambdaQueryWrapper<UserCollectionChainLog> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserCollectionChainLog::getToUserCollectionId, toUserCollectionId);
        wrapper.orderByDesc(UserCollectionChainLog::getId);
        wrapper.last("limit 1");
        return getOne(wrapper);
    }

    public Boolean updateContractAddressAndDeployTransactionHashAndTransactionHashAndAddressAndTokenIdAndStatusById(Long id, String contractAddress, String deployTransactionHash, String transactionHash, String address, Integer tokenId, UserChainLogStatusEnum userChainLogStatusEnum) {
        LambdaUpdateWrapper<UserCollectionChainLog> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(UserCollectionChainLog::getId, id);
        wrapper.set(UserCollectionChainLog::getContractAddress, contractAddress);
        wrapper.set(UserCollectionChainLog::getDeployTransactionHash, deployTransactionHash);
        wrapper.set(UserCollectionChainLog::getTransactionHash, transactionHash);
        wrapper.set(UserCollectionChainLog::getAddress, address);
        wrapper.set(UserCollectionChainLog::getTokenId, tokenId);
        wrapper.set(UserCollectionChainLog::getStatus, userChainLogStatusEnum);
        return update(wrapper);
    }

    public UserCollectionChainLog getOneByTransactionHashAndStatus(String transactionHash, UserChainLogStatusEnum userChainLogStatusEnum, Integer tokenId) {
        LambdaQueryWrapper<UserCollectionChainLog> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserCollectionChainLog::getTransactionHash, transactionHash);
        wrapper.eq(UserCollectionChainLog::getStatus, userChainLogStatusEnum);
        wrapper.eq(UserCollectionChainLog::getTokenId, tokenId);
        wrapper.last("order by id desc limit 1");
        return getOne(wrapper);
    }

    public Boolean updateStatusById(Long id, UserChainLogStatusEnum userChainLogStatusEnum) {
        LambdaUpdateWrapper<UserCollectionChainLog> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(UserCollectionChainLog::getId, id);
        wrapper.set(UserCollectionChainLog::getStatus, userChainLogStatusEnum);
        return update(wrapper);
    }

    public UserCollectionChainLog getOneByTransactionHashAndTokenId(String transactionHash, Integer tokenId) {
        LambdaQueryWrapper<UserCollectionChainLog> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserCollectionChainLog::getTransactionHash, transactionHash);
        wrapper.eq(ObjectUtil.isNotNull(tokenId), UserCollectionChainLog::getTokenId, tokenId);
        wrapper.last("order by id desc limit 1");
        return getOne(wrapper);
    }

    public boolean updateStatusAndTransactionHashById(Long id, UserChainLogStatusEnum status, String transactionHash) {
        LambdaUpdateWrapper<UserCollectionChainLog> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(UserCollectionChainLog::getId, id);
        wrapper.set(UserCollectionChainLog::getStatus, status);
        wrapper.set(UserCollectionChainLog::getTransactionHash, transactionHash);
        return update(new UserCollectionChainLog(), wrapper);
    }

}